package pl.edu.agh.iosr.gamblingzone.dao.ejb;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import pl.edu.agh.iosr.gamblingzone.dao.BettingSlipDAO;
import pl.edu.agh.iosr.gamblingzone.model.BettingSlip;
import pl.edu.agh.iosr.gamblingzone.model.User;

/**
 * The Class BettingSlipDAOBean.
 */
public class BettingSlipDAOBean extends GenericDAOBean<BettingSlip, Long> 
implements BettingSlipDAO {

	/* (non-Javadoc)
	 * @see pl.edu.agh.iosr.gamblingzone.dao.BettingSlipDAO#getBettingSlipsBetween(pl.edu.agh.iosr.gamblingzone.model.User, java.util.Date, java.util.Date, int)
	 */
	@SuppressWarnings("unchecked")
	public List<BettingSlip> getBettingSlipsBetween(User user, Date dateBegin, Date dateEnd, int page) {

		EntityManager em = getEntityManager();
		if (em == null) {
			throw new IllegalStateException("Entity manager shouldn't be null");
		}
		Query q = em.createQuery("select b from BETTING_SLIPS b" +
				" where b.creationDate >= :startDate" +
				" and b.creationDate <= :endDate " +
				" and b.owner = :owner"+
		" order by b.creationDate asc")
		.setMaxResults(getPageSize())
		.setFirstResult(page*getPageSize())
		.setParameter("startDate", dateBegin)
		.setParameter("endDate", dateEnd)
		.setParameter("owner", user);

		List<BettingSlip> retList = q.getResultList();

		if (retList == null) {
			return new LinkedList<BettingSlip>();
		}

		return retList;
	}

	/* (non-Javadoc)
	 * @see pl.edu.agh.iosr.gamblingzone.dao.BettingSlipDAO#getPageCount(pl.edu.agh.iosr.gamblingzone.model.User)
	 */
	public int getPageCount(User user) {		
		return getPageCount(user, "owner");
	}

	/* (non-Javadoc)
	 * @see pl.edu.agh.iosr.gamblingzone.dao.BettingSlipDAO#findAll(pl.edu.agh.iosr.gamblingzone.model.User, int)
	 */
	public List<BettingSlip> findAll(User user, int page) {
		return findAll(user, "owner", page);
	}

	/* (non-Javadoc)
	 * @see pl.edu.agh.iosr.gamblingzone.dao.BettingSlipDAO#getEntitiesCount(pl.edu.agh.iosr.gamblingzone.model.User)
	 */
	public int getEntitiesCount(User user) {
		return getEntitiesCount(user, "owner");
	}

	/* (non-Javadoc)
	 * @see pl.edu.agh.iosr.gamblingzone.dao.BettingSlipDAO#getBettingSlipsBetweenCount(pl.edu.agh.iosr.gamblingzone.model.User, java.util.Date, java.util.Date)
	 */
	public int getBettingSlipsBetweenCount(User user,
			Date dateBegin, Date dateEnd) {
		EntityManager em = getEntityManager();
		if (em == null) {
			throw new IllegalStateException("Entity manager shouldn't be null");
		}
		Query q = em.createQuery("select count(b) from BETTING_SLIPS b" +
				" where b.creationDate >= :startDate" +
				" and b.creationDate <= :endDate " +
		" and b.owner = :owner")
		.setParameter("startDate", dateBegin)
		.setParameter("endDate", dateEnd)
		.setParameter("owner", user);

		Number resNumber = (Number)q.getSingleResult();;

		if (resNumber == null) {
			return 0;
		}

		return resNumber.intValue();
	}

	/* (non-Javadoc)
	 * @see pl.edu.agh.iosr.gamblingzone.dao.BettingSlipDAO#getBettingSlipsBetweenPageCount(pl.edu.agh.iosr.gamblingzone.model.User, java.util.Date, java.util.Date)
	 */
	public int getBettingSlipsBetweenPageCount(User user,
			Date dateBegin, Date dateEnd) {

		int slipsCount = getBettingSlipsBetweenCount(user, dateBegin, dateEnd);

		int retNum = slipsCount/getPageSize();
		if (slipsCount%getPageSize() > 0) {
			retNum++;
		}

		return retNum;
	}

}
